#include "heibai_rule.h"
#include <string.h>

CHBRule::CHBRule(CHBChessBoard * board)
{
	m_vBoard = board;
	memset(m_ssChess, 0, 10*10);
	m_ssChess[4][4] = USER2;
	m_ssChess[4][5] = USER1;
	m_ssChess[5][4] = USER1;
	m_ssChess[5][5] = USER2;
	m_vBoard->PutChess(4, 4, USER2);
	m_vBoard->PutChess(4, 5, USER1);
	m_vBoard->PutChess(5, 4, USER1);
	m_vBoard->PutChess(5, 5, USER2);
	m_nWinPlayer = 0;
}

CHBRule::~CHBRule()
{
}

int CHBRule::PutChess(int x, int y, int user, int bShow)
{
	if(m_ssChess[y][x] != 0)
		return 0;
	int sum = 0;
	sum += TurnDir(x, y, 1, 1, user, bShow);
	sum += TurnDir(x, y, 1, 0, user, bShow);
	sum += TurnDir(x, y, 1, -1, user, bShow);
	sum += TurnDir(x, y, 0, 1, user, bShow);
	sum += TurnDir(x, y, 0, -1, user, bShow);
	sum += TurnDir(x, y, -1, 1, user, bShow);
	sum += TurnDir(x, y, -1, 0, user, bShow);
	sum += TurnDir(x, y, -1, -1, user, bShow);
	if(sum > 0){
		m_ssChess[y][x] = user;
		if(bShow == 1)
			m_vBoard->PutChess(x, y, user);
	}
	return sum;
}

int CHBRule::TurnDir(int x, int y, int tx, int ty, int user, int bShow)
{
	int sx = x + tx;
	int sy = y + ty;
	if(m_ssChess[sy][sx] == user || m_ssChess[sy][sx] == 0)
		return 0;
	int n = 0;
	while(1){
		n++;
		sx += tx;
		sy += ty;
		if(m_ssChess[sy][sx] == 0)
			return 0;
		if(m_ssChess[sy][sx] == user){
			sx = x;
			sy = y;
			do{
				sx += tx;
				sy += ty;
				m_ssChess[sy][sx] = user;
				if(bShow == 1)
					m_vBoard->PutChess(sx, sy, user);
			}while(m_ssChess[sy+ty][sx+tx] != user);
			return n;
		}
	}
}

int  CHBRule::SetUser(CHBUser * user, int i)
{
	int n = i - 1;
	int k;
	if(i == 1)
	  k = 1;
	else
	  k = -1;
	m_user[n] = user;
	m_user[n]->SetUser(k);
	m_user[n]->SetRule(this);
	return 0;
}

void CHBRule::GetSig(int &x, int &y)
{
	m_vBoard->GetSignal(x, y);
}

int CHBRule::Run()
{
	int x;
	int y;
	m_vBoard->SetProfile(1, 2, 2, 1);
	m_vBoard->ShowBoard();
	int user = USER1;
	int user1Chess;
	int user2Chess;
	int un = 0;
	while(1){
		do{
			m_user[un]->Play();
			m_user[un]->GetChess(x,y);
		}while(PutChess(x,y, user) == 0);
		GetUserChess(user1Chess, user2Chess);
		int usern = GetNextPlay(user);
		if(usern != user){
			un = un ^ 1;
			user = usern;
		}
		if(user == HEIBAI_END){
			if(user1Chess > user2Chess)
				m_nWinPlayer = USER1;
			if(user2Chess > user1Chess)
				m_nWinPlayer = USER2;
			m_vBoard->SetProfile(2, user1Chess, user2Chess, m_nWinPlayer);
		}else
			m_vBoard->SetProfile(1, user1Chess, user2Chess, user);
		m_vBoard->ShowBoard();
		if(user == HEIBAI_END)
			return 0;
	}
	return 0;
}

int CHBRule::GetOtherUser(int user)
{
	if(user == USER1)
		return USER2;
	else if(user == USER2)
		return USER1;
	else
		return 0;
}

int CHBRule::GetNextPlay(int user)
{
	int nNextUser = GetOtherUser(user);
	if(CanPlay(nNextUser))
		return nNextUser;
	nNextUser = user;
	if(CanPlay(nNextUser))
		return nNextUser;

	int user1Chess;
	int user2Chess;
	GetUserChess(user1Chess, user2Chess);
	if(user1Chess > user2Chess)
		m_nWinPlayer = USER1;
	if(user2Chess > user1Chess)
		m_nWinPlayer = USER2;
	return HEIBAI_END;
}

int CHBRule::CanPlay(int user)
{
	CHBRule testRule(*this);
	return testRule.TestPut(user);
}

int CHBRule::TestPut(int user)
{
	int i,j;
	int nRet;
	for(i = 1; i < 9; i++){
		for(j = 1; j < 9; j++){
			nRet = PutChess(i, j, user, 0);
			if(nRet > 0)
				return nRet;
		}
	}
	return 0;
}

void CHBRule::GetUserChess(int &user1, int &user2)
{
	user1 = 0;
	user2 = 0;
	int i , j;
	for(i = 1; i < 9; i++){
		for(j = 1; j < 9; j++){
			if(m_ssChess[i][j] == USER1)
				user1++;
			else if(m_ssChess[i][j] == USER2)
				user2++;
		}
	}
}
